﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Threading.Tasks;
using MatrixWebApiCore.Common;
using MatrixWebApiCore.Dao;
using MatrixWebApiCore.Entity;
using MatrixWebApiCore.Entity.Enum;
using MatrixWebApiCore.Entity.RequestModel;
using MatrixWebApiCore.Filter;
using MatrixWebApiCore.HttpRequest;
using MatrixWebApiCore.IDao;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;

namespace MatrixWebApiCore.Controllers
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    public class ChartDataController : Controller
    {
        private IGroupChartsRepository _group;
        private ICombinationGroupChartsRepository _combinationGroup;
        private IMemoryCache _cache;

        public ChartDataController(IGroupChartsRepository group, ICombinationGroupChartsRepository combinationGroup, IMemoryCache memoryCache)
        {
            _group = group;
            _combinationGroup = combinationGroup;
            _cache = memoryCache;
        }

        /// <summary>
        /// 获取各个指标的源数据
        /// </summary>
        /// <returns></returns>
        [HttpPost("TargetSourse")]
        [TokenFilter]
        public async Task<ActionResult> TargetSourse([FromBody]TargetParames parames)
        {
#if DEBUG
            MessageHelper.LogInfo("TargetSourse开始查询...");
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
#endif

            #region 参数验证         
            if (parames == null)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "无效参数" });
            }
            if (parames.AnalysisId == 0)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "分析id不能为空" });
            }
            if (string.IsNullOrWhiteSpace(parames.StartDate))
            {
                return Json(new BackResult<object>() { Success = false, Msg = "统计开始日期不能为空" });
            }
            if (string.IsNullOrWhiteSpace(parames.EndDate))
            {
                return Json(new BackResult<object>() { Success = false, Msg = "统计结束日期不能为空" });
            }
            try
            {
                Convert.ToDateTime(parames.StartDate);
            }
            catch (Exception)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "统计开始日期不能为空" });
            }
            try
            {
                Convert.ToDateTime(parames.EndDate);
            }
            catch (Exception)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "统计结束日期不能为空" });
            }
            string[] targetIds = parames.TargetValue.Split(',');
            var enumList = EnumHelpter.GetNVCFromEnumValue(typeof(TargetEnum));
            //检查是否存在指标id
            foreach (var targetId in targetIds)
            {
                int tint = 0;
                try
                {
                    tint = Convert.ToInt32(targetId);
                }
                catch (Exception)
                {
                    return Json(new BackResult<object>() { Success = false, Msg = "指标id必须是正整数" });
                }
                var isHave = enumList.AsParallel().Any(w => w.Value == tint);
                if (!isHave)
                {
                    return Json(new BackResult<object>() { Success = false, Msg = "不存在指标id=" + targetId });
                }
            }
            if (parames.Type == 0)
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            List<int> checkTypes = new List<int>() { 1, 2 };
            if (!checkTypes.Contains(parames.Type))
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            #endregion

            string cacheKey = $"TargetSourse_{parames.AnalysisId}_{parames.StartDate}_{parames.EndDate}_{parames.TargetValue}_{parames.Type}";
            object cacheObj = null;
            bool isHaveVal = _cache.TryGetValue(cacheKey, out cacheObj);
            if (cacheObj != null)
            {
                return Json(new BackResult<object>() { Data = cacheObj });
            }
            StringValues tokenObj;
            Request.Headers.TryGetValue("Authorization", out tokenObj);
            string token = tokenObj.ToString();
            Dictionary<EnumItem, Task<BackResult<object>>> taskDict = new Dictionary<EnumItem, Task<BackResult<object>>>();
            IwebHttpClienBase _clientData = null;
            switch (parames.Type)
            {
                case 1:
                    _clientData = new WebClientData(_cache);
                    break;
                case 2:
                    _clientData = new CombinationWebClientData(_cache);
                    break;
            }
            Parallel.ForEach(targetIds, item =>
            {
                int _targetValue = Convert.ToInt32(item);
                string _targetName = ((TargetEnum)_targetValue).ToString();
                string _description = enumList.AsParallel().FirstOrDefault(w => w.Value == _targetValue).Description;
                EnumItem enumItem = new EnumItem() { Description = _description, Name = _targetName, Value = _targetValue };
                Task<BackResult<object>> task = null;
                //获取数据
                switch (_targetValue)
                {
                    //基本信息,测试通过，有缓存
                    case 10:
                        task = _clientData.BasicInfoAsync(token, parames);
                        break;

                    //风险指标,测试通过，有缓存
                    case 20:
                        task = _clientData.RiskIndicator(token, parames);
                        break;

                    //业绩表现,测试通过，有缓存
                    case 30:
                        task = _clientData.Performance(token, parames);
                        break;

                    //今年业绩(周)，有缓存
                    case 40:
                        task = _clientData.ThisYearPerformanceWeek(token, parames);
                        break;

                    //本年度周收益率，有缓存
                    case 50:
                        task = _clientData.ThisYearWeekIncomeRate(token, parames);
                        break;

                    //市场信息(市场指数累计收益率) ，有缓存
                    case 60:
                        task = _clientData.AllBenchmarkYieldRate(token, parames.AnalysisId, parames.StartDate, parames.EndDate);
                        break;

                    //持仓信息，有缓存
                    case 70:
                        task = _clientData.AssetAllocation(token, parames);
                        break;

                    //行业配置,测试通过，有缓存
                    case 80:
                        task = _clientData.IndustryStructure(token, parames);
                        break;

                    //重仓证券,测试通过，有缓存
                    case 90:
                        task = _clientData.HeavySecuritie(token, parames);
                        break;
                }
                taskDict.Add(enumItem, task);
            });
            await Task.WhenAll(taskDict.Values);
            ConcurrentBag<BackTargetData> list = new ConcurrentBag<BackTargetData>();
            Parallel.ForEach(taskDict, item =>
            {
                list.Add(new BackTargetData() { Description = item.Key.Description, TargetName = item.Key.Name, TargetVal = item.Key.Value, Data = item.Value.Result });
            });
            List<BackTargetData> sortList = list.OrderBy(w => w.TargetVal).ToList();
            //缓存有效300分钟         
            _cache.Set(cacheKey, sortList, DateTimeOffset.Now.AddSeconds(SysCoinfgData.MemoryCacheLiveTime));
#if DEBUG
            stopwatch.Stop();
            MessageHelper.LogInfo("TargetSourse执行耗时：" + stopwatch.ElapsedMilliseconds);
#endif
            return Json(new BackResult<object>() { Data = sortList });
        }

        /// <summary>
        /// 获取所有基准
        /// </summary>
        /// <returns>返回列表</returns>
        [HttpGet("AllBenchmark")]
        //[TokenFilter]
        public async Task<ActionResult> AllBenchmark()
        {
            //StringValues tokenObj;
            //Request.Headers.TryGetValue("Authorization",out tokenObj);        
            //string token = tokenObj.ToString();
            string url = SysCoinfgData.ApiBaesURL + "/api/DropDownList/GetBenchmarkCode";
            string backData = await HttpHelper.WebClientGetAsync(url, "");
            object obj = Newtonsoft.Json.JsonConvert.DeserializeObject<object>(backData);
            return Json(new BackResult<object>() { Data = obj });
        }

        /// <summary>
        /// 获取指标列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("TargetList/{type}")]
        public async Task<IActionResult> TargetList(int type)
        {
            if (type == 0)
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            List<int> checkTypes = new List<int>() { 1, 2 };
            if (!checkTypes.Contains(type))
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            var dict = EnumHelpter.GetNVCFromEnumValue(typeof(TargetEnum));
            List<object> list = new List<object>() { };
            List<object> typeList = new List<object>();
            if (type == 1)
            {
                //创盈一号周报类型           
                typeList.Add(new { Description = "创盈一号周报", EngName = "ChuangYingNo1", Id = "T10", Childs = dict });
            }
            else if (type == 2)
            {
                //实盈Alpha自营盘周报           
                typeList.Add(new { Description = "实盈Alpha自营盘周报", EngName = "Combn1", Id = "CN20", Childs = dict });
            }
            await Task.CompletedTask;
            return Json(new BackResult<object>() { Data = typeList });
        }

        /// <summary>
        /// 获取基金或组合分析列表 
        /// </summary>
        /// <param name="parames"></param>        
        /// <returns></returns>
        [HttpPost("FundList")]
        [TokenFilter]
        public async Task<ActionResult> FundList([FromBody]FundListParames parames)
        {
            if (parames == null)
            {
                return Json(new BackResult<object>() { Msg = "无效参数", Success = false });
            }
            if (parames.Type == 0)
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            List<int> checkTypes = new List<int>() { 1, 2 };
            if (!checkTypes.Contains(parames.Type))
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            StringValues tokenObj;
            Request.Headers.TryGetValue("Authorization", out tokenObj);
            string token = tokenObj.ToString();
            object obj = null;
            string url = string.Empty;
            switch (parames.Type)
            {
                //基金分析
                case 1:
                    url = SysCoinfgData.ApiBaesURL + "/api/ProductManager/PageData";
                    obj = new
                    {
                        Body = new
                        {
                            Page = new
                            {
                                PageIndex = parames.PageIndex,
                                PageSize = parames.PageSize,
                                //OrderFile = "EndTime",
                                SortType = 1
                            },
                            RequestParams = new
                            {
                                IsPublic = false,
                                Name = "",
                                //ValueSeach=null,
                                //Strategys=null,
                                //DateTimeSeach=null,
                                //StartTimeSeach=null,
                                //Name=null,
                            }
                        }
                    };
                    break;

                //组合分析
                case 2:
                    url = SysCoinfgData.ApiBaesURL + "/api/PerformanceAnalysis/PageData";
                    obj = new
                    {
                        Body = new
                        {
                            Page = new
                            {
                                PageIndex = parames.PageIndex,
                                PageSize = parames.PageSize,
                                SortType = 1
                            },
                            RequestParams = new
                            {
                                DateTimeSeach = new
                                {
                                    EndTime = parames.EndTime,
                                    Month = ""
                                },
                                IsPublic = false,
                                StartTimeSeach = new { EndTime = parames.EndTime },
                                ValueSeach = new List<object>()
                            }
                        }
                    };
                    break;
            }
            string data = await HttpHelper.WebClientPostAsync(url, Newtonsoft.Json.JsonConvert.SerializeObject(obj), token);
            dynamic jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(data);
            if (Convert.ToInt32(jsonObject.Head.Code.Value) > 400)
            {
                return Json(new BackResult<object>() { Success = false, Msg = jsonObject.Head.Message });
            }
            return Json(new BackResult<object>() { Data = jsonObject.Result });
        }

        /// <summary>
        /// 保存混合图
        /// </summary>
        /// <param name="parames"></param>
        /// <returns></returns>
        [HttpPost("Save")]
        public async Task<ActionResult> SaveGroup([FromBody]SavePrames parames)
        {
            if (parames == null)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "无效参数" });
            }
            if (parames.AnalysisId == 0)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "分析id不能为零" });
            }
            if (string.IsNullOrWhiteSpace(parames.JsonData))
            {
                return Json(new BackResult<object>() { Success = false, Msg = "分析id不能为零" });
            }
            if (parames.Type == 0)
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            List<int> checkTypes = new List<int>() { 1, 2 };
            if (!checkTypes.Contains(parames.Type))
            {
                return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
            }
            try
            {
                Newtonsoft.Json.JsonConvert.DeserializeObject(parames.JsonData);
            }
            catch (Exception)
            {
                return Json(new BackResult<object>() { Success = false, Msg = "JsonData不是有效的json格式" });
            }
            return await Task.Run(() =>
            {
                //第一次保存
                if (string.IsNullOrWhiteSpace(parames.SaveId))
                {
                    GroupCharts model = new GroupCharts();
                    model.Id = Guid.NewGuid();
                    model.TargetStr = parames.TargetStr;
                    model.AnalysisId = parames.AnalysisId;
                    model.StartDate = parames.StartDate;
                    model.EndDate = parames.EndDate;
                    model.CreateTime = DateTime.Now;
                    //model.UpdateTime = DateTime.Now;
                    model.Creator = parames.UserName;
                    model.ReportName = parames.ReportName;
                    model.SaveJson = parames.JsonData;
                    if (parames.Type == 1)
                    {
                        int count = _group.Add(model);
                    }
                    else
                    {
                        string json = Newtonsoft.Json.JsonConvert.SerializeObject(model);
                        CombinationGroupCharts combinationModel = Newtonsoft.Json.JsonConvert.DeserializeObject<CombinationGroupCharts>(json);
                        int count = _combinationGroup.Add(combinationModel);
                    }
                }
                else
                {
                    //更新数据
                    Guid _guid;
                    try
                    {
                        _guid = Guid.Parse(parames.SaveId);
                    }
                    catch (Exception)
                    {
                        return Json(new BackResult<object>() { Msg = "SaveId无效，不是正确的guid" });
                    }
                    //基金分析
                    if (parames.Type == 1)
                    {
                        var oldModel = _group.Get(w => w.Id == _guid);
                        if (oldModel == null)
                        {
                            return Json(new BackResult<object>() { Msg = "不存在该报告id" });
                        }
                        oldModel.TargetStr = parames.TargetStr;
                        oldModel.AnalysisId = parames.AnalysisId;
                        oldModel.StartDate = parames.StartDate;
                        oldModel.EndDate = parames.EndDate;
                        oldModel.UpdateTime = DateTime.Now;
                        oldModel.LatestOperator = parames.UserName;//最新操作人
                        oldModel.ReportName = parames.ReportName;
                        oldModel.SaveJson = parames.JsonData;
                        int count = _group.Update(oldModel);
                    }
                    //组合分析
                    else
                    {
                        var oldModel = _combinationGroup.Get(w => w.Id == _guid);
                        if (oldModel == null)
                        {
                            return Json(new BackResult<object>() { Msg = "不存在该报告id" });
                        }
                        oldModel.TargetStr = parames.TargetStr;
                        oldModel.AnalysisId = parames.AnalysisId;
                        oldModel.StartDate = parames.StartDate;
                        oldModel.EndDate = parames.EndDate;
                        oldModel.UpdateTime = DateTime.Now;
                        oldModel.LatestOperator = parames.UserName;//最新操作人
                        oldModel.ReportName = parames.ReportName;
                        oldModel.SaveJson = parames.JsonData;
                        int count = _combinationGroup.Update(oldModel);
                    }
                }
                return Json(new BackResult<object>() { Msg = "保存成功" });
            });
        }

        /// <summary>
        /// 获取保存的报告，当id有值返回具体报告数据，为空返回报告列表
        /// </summary>
        /// <param name="parames">报告id</param>
        /// <returns></returns>
        [HttpPost("ChartsData")]
        public async Task<ActionResult> GroupChartsData([FromBody]BaseRequest parames)
        {
            return await Task.Run(() =>
            {
                if (parames == null)
                {
                    return Json(new BackResult<object>() { Msg = "无效参数", Success = false });
                }
                if (parames.Type == 0)
                {
                    return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
                }
                List<int> checkTypes = new List<int>() { 1, 2 };
                if (!checkTypes.Contains(parames.Type))
                {
                    return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
                }
                if (string.IsNullOrWhiteSpace(parames.Id))
                {
                    object backList = new object();
                    //获取报告列表
                    if (parames.Type == 1)
                    {
                        var list = _group.GetAll().OrderByDescending(w => w.CreateTime).ToList();
                        Parallel.ForEach(list, item =>
                        {
                            item.SaveJson = "";
                        });
                        backList = list;
                    }
                    //组合分析
                    else if (parames.Type == 2)
                    {
                        var list = _combinationGroup.GetAll().OrderByDescending(w => w.CreateTime).ToList();
                        Parallel.ForEach(list, item =>
                        {
                            item.SaveJson = "";
                        });
                        backList = list;
                    }
                    return Json(new BackResult<object>() { Data = backList });
                }
                else
                {
                    //查询具体报告数据
                    Guid _guid;
                    try
                    {
                        _guid = Guid.Parse(parames.Id);
                    }
                    catch (Exception)
                    {
                        return Json(new BackResult<object>() { Success = false, Msg = "参数id为无效的guid字符串" });
                    }
                    //基金分析
                    if (parames.Type == 1)
                    {
                        var data = _group.Get(w => w.Id == _guid);
                        return Json(new BackResult<object>() { Data = data });
                    }
                    //组合分析
                    else
                    {
                        var data = _combinationGroup.Get(w => w.Id == _guid);
                        return Json(new BackResult<object>() { Data = data });
                    }
                }
            });
        }

        /// <summary>
        /// 删除已保存的报告
        /// </summary>
        /// <param name="parames">传主键id</param>
        /// <returns></returns>
        [HttpPost("Delete")]
        public async Task<ActionResult> DeleteSavedReport([FromBody]BaseRequest parames)
        {
            return await Task.Run(() =>
            {
                if (parames == null)
                {
                    return Json(new BackResult<object>() { Msg = "无效参数", Success = false });
                }
                if (string.IsNullOrWhiteSpace(parames.Id))
                {
                    return Json(new BackResult<object>() { Msg = "主键Id必须", Success = false });
                }
                if (parames.Type == 0)
                {
                    return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
                }
                List<int> checkTypes = new List<int>() { 1, 2 };
                if (!checkTypes.Contains(parames.Type))
                {
                    return Json(new BackResult<object>() { Msg = "Type参数值无效", Success = false });
                }
                //查询具体报告保存的数据
                Guid _guid;
                try
                {
                    _guid = Guid.Parse(parames.Id);
                }
                catch (Exception)
                {
                    return Json(new BackResult<object>() { Success = false, Msg = "参数id为无效的guid字符串" });
                }
                //基金分析
                if (parames.Type == 1)
                {
                    var data = _group.Get(w => w.Id == _guid);
                    if (data == null)
                    {
                        return Json(new BackResult<object>() { Success = false, Msg = "不存在此报告" });
                    }
                    _group.Delete(w => w.Id == _guid);
                    return Json(new BackResult<object>() { Msg = "删除成功" });
                }
                //组合分析
                else
                {
                    var data = _combinationGroup.Get(w => w.Id == _guid);
                    if (data == null)
                    {
                        return Json(new BackResult<object>() { Success = false, Msg = "不存在此报告" });
                    }
                    _combinationGroup.Delete(w => w.Id == _guid);
                    return Json(new BackResult<object>() { Msg = "删除成功" });
                }
            });
        }

    }
}
